package net.tp.algo.localsearch;

import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Trung Phan
 *
 */
public class HillDescender {

    public static Logger logger = Logger.getLogger(HillDescender.class.getName());

    public static Random random = new Random();

    public static State search(State initState, int iterations, double acceptRate) {

        State activeState = initState;
        State minState = initState;
        double minEnergy = minState.energy();

        for (int i = 0; i < iterations; i++) {
            double activeEnergy = activeState.energy();

            if (i % 10000 == 0 && logger.isLoggable(Level.FINE)) logger.fine(String.format("Energy at %d: %f", i, activeEnergy));

            State nextStep = activeState.step();
            double nextEnergy = nextStep.energy();
            if (nextEnergy < activeEnergy || random.nextDouble() < acceptRate) {
                activeState = nextStep;
                if (nextEnergy < minEnergy) {
                    minState = nextStep;
                    minEnergy = nextEnergy;
                }
            }

        }

        return minState;
    }

}
